<template>
  <div class="department-container">
    <div class="app-container">
      <el-card>
        <!-- 用一个行列布局 -->
        <el-row type="flex" justify="space-between" align="middle" style="height: 40px">
          <el-col :span="20">
            <svg-icon icon-class="bank" /><span> 江苏传智播客教育科技股份有限公司</span>
          </el-col>
          <el-col :span="4">
            <el-row type="flex" justify="end">
              <!-- 两个内容 -->
              <el-col>负责人</el-col>
              <!-- 下拉菜单 element -->
              <el-col>
                <el-dropdown>
                  <span>
                    操作<i class="el-icon-arrow-down" />
                  </span>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item @click.native="hAddOrEdit('',false)">添加子部门</el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
              </el-col>
            </el-row>
          </el-col>
        </el-row>
        <!-- 树形结构  -->
        <el-tree default-expand-all :data="list">
          <template v-slot="{data}">
            <el-row type="flex" justify="space-between" align="middle" style="height: 40px;width:100%">
              <el-col :span="20">
                <span> {{ data.name }}</span>
              </el-col>
              <el-col :span="4">
                <el-row type="flex" justify="end">
                  <!-- 两个内容 -->
                  <el-col>{{ data.manager }}</el-col>
                  <!-- 下拉菜单 element -->
                  <el-col>
                    <el-dropdown>
                      <span>
                        操作<i class="el-icon-arrow-down" />
                      </span>
                      <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item @click.native="hAddOrEdit(data.id,false)">添加子部门</el-dropdown-item>
                        <el-dropdown-item @click.native="hAddOrEdit(data.id,true)">编辑部门</el-dropdown-item>
                        <!-- v-if 判断菜单有没有子菜单 , 如果有子菜单 就不显示删除部门 -->
                        <el-dropdown-item v-if="!data.children.length" @click.native="hdel(data.id)">删除部门</el-dropdown-item>
                      </el-dropdown-menu>
                    </el-dropdown>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-tree>
      </el-card>
    </div>
    <!--
      是否可以通过点击 (遮罩背景)modal 关闭 Dialog
      是否可以通过按下 ESC 关闭 Dialog -->
    <el-dialog
      :title="dialogTitle"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :visible.sync="showDialog"
    >
      <!-- 烤串命名法: 组件名 或者 属性名  kebab Case
           驼峰命名法: 变量名             camle Case
          这两种命名方式: 在组件使用 / Props传值时 可以互相替代使用 -->

      <!-- 方案1: v-if 最推荐 , 无bug,  但是会多次 创建销毁
        AddOrEdit 子组件的生命周期与 dialog的显示隐藏 同步  v-if 会在DOM 上添加或删除, 如果用在组件上,就会创建和销毁组件-->
      <AddOrEdit v-if="showDialog" :id="curId" ref="addOrEdit" :origin-list="originList" :is-edit="isEdit" @success="hsuccess" @close="hclose" />

      <!-- 方案2: 点击编辑后, 手动调用 $refs  调用子组件的方法发请求获取数据, 减少组件的创建和销毁, 提高性能,但是还要清除数据 ,网速慢会影响用户体验-->
      <!-- <AddOrEdit :id="curId" ref="addOrEdit" :is-edit="isEdit" @success="hsuccess" /> -->

      <!-- 方案3: 在子组件中 使用watch 侦听id 的变化(每次点击id都会变化), 只要修改了就发请求获取最新的 部门详情(数据回填) -->

      <!-- 小结:
          方案1(★推荐使用): 用法简单, 贴合实际, Bug最少, 但是会频繁创建销毁子组件
          方案2 / 3: 不会频繁创建销毁子组件, 但是需要额外处理很多小Bug, 比如: 编辑后再点添加(也触发了数据回填)
           -->

    </el-dialog>
  </div>
</template>

<script>
import { getDepartments, delDepartments } from '@/api/departments'
import { tranListToTreeData } from '@/utils'
import AddOrEdit from './deptDialog' // 文件名最好起 组件类型, 组件标签名可以起 功能
export default {
  name: 'Departments',
  components: { AddOrEdit },
  data() {
    return {
      list: [],
      showDialog: false,
      curId: '',
      isEdit: '',
      originList: [] // 平铺结构数组
      // list: [{
      //   name: '财务部',
      //   manager: '刘备',
      //   children: [{
      //     name: '财务核算部',
      //     manager: '张飞'
      //   },
      //   {
      //     name: '税务核算部',
      //     manager: '关羽'
      //   }
      //   ]
      // }]
      // defaultProps: { // 默认 label 控制标题名字, children 控制 子菜单名字
      //   children: 'children',
      //   label: 'label'
      // }
    }
  },
  computed: {
    dialogTitle() { // 对话框的标题
      return this.isEdit ? '编辑部门' : '添加子部门'
    }
  },
  created() {
    this.loadDepartments()
  },
  methods: {
    async loadDepartments() { // 查询企业的部门列表 并渲染
      try {
        const res = await getDepartments()
        // console.log(res.data.depts)
        // 由于业务中传智教育的pid是:-1，它是最高级的节点
        // shift 从数组头部取出一个元素
        res.data.depts.shift() // shift()的返回值 是一个对象,里面是被删除的元素 (传智教育)

        // // 用工具函数把 平铺的数组转成 树型数据
        this.list = tranListToTreeData(res.data.depts)

        // 作内部系统的表单校验,  所有的部门编号 和 同级菜单下的部门名称不能相同
        // 所以需要以下数据 父传子 解构item时需要加小括号; return 对象时可以 去掉 return 再加个小括号
        this.originList = res.data.depts.map(({ id, pid, name, code }) => { return { id, pid, name, code } })
        // this.originList = res.data.depts.map(({ id, pid, name, code }) => { ({ id, pid, name, code }) })

        // console.log(res.data.depts)
        // console.log(this.list)
      } catch (error) {
        console.log('获取部门信息失败,原因:', error)
      }
    },
    hAddOrEdit(id, isEdit) { // 点击添加 或 编辑
      this.showDialog = true
      this.curId = id
      this.isEdit = isEdit

      // // 方案2: 点击编辑后, 手动调用子组件的 部门详情请求 (进行数据回填)
      // if (isEdit) {
      //   // console.log(this.$refs)
      //   // DOM 更新是异步的 此时子组件还未创建
      //   // 需要等待下一次 DOM 更新完毕后再获取子组件
      //   this.$nextTick(() => {
      //     // 一般情况下不到万不得已, 不要随意调用子组件的函数, 容易导致维护困难
      //     // 回调函数就是下一次 DOM 更新完毕后自动执行的
      //     // 调用子组件的 loadDepartment 函数

      //     this.$refs.addOrEdit.loadDepartDetail()
      //   })

      //   // 以下代码完全等同于上面的回调
      //   // await this.$nextTick()
      //   // this.$refs.addOrEdit.loadDepartment()
      // }
    },
    async hdel(id) { // 点击 删除部门 await + .catch
      const result = await this.$confirm('确定要删除此部门吗?', '提示', {
        type: 'warning'
      }).catch(e => e)

      if (result !== 'confirm') return

      const res = await delDepartments(id).catch(e => this.$message.error(e.message))
      this.$message.success(res.message)
      this.loadDepartments()
    },
    hsuccess() { // 子组件点确定后 ,关闭 对话框
      this.showDialog = false
      // 更新 部门列表
      this.loadDepartments()
    },
    hclose() { // 子组件点击 取消, 触发父组件 对话框的隐藏
      this.showDialog = false
    }
  }

}

</script>
